﻿
using System;
using System.Collections;
using System.Collections.Generic;
using com.diagnosis.tool.xml;

namespace DiagnosisToolBL
{
    public class DiseasesBuilderData
    {
        private Dictionary<string, ExtendedDiseaseForBuilder> mDiseases;

        private Dictionary<string, Int32> mSymptomToID;
        private Dictionary<Int32, List<string>> mIDToSymptoms;

        private int mCurrentMaxID = -1;

        private DiagnosisToolData mToolData;

        private ExtendedDiseaseForBuilder mWorkingDiseaseForBuilder;

        public Dictionary<string, ExtendedDiseaseForBuilder> GetDiseases()
        {
            return mDiseases;
        }

        public void LoadFromXml(String pFilePath)
        {
            mSymptomToID = new Dictionary<string, int>();
            mIDToSymptoms = new Dictionary<int, List<string>>(); 
          
            var xmlMngr = DiagnosisToolXmlMngr.GetInstance(pFilePath);
            mToolData = xmlMngr.DiagnosisToolData;
            
            // Convert the symptoms to the maps
            foreach (var curSameSymp in mToolData.SameSymptoms)
            {
                var id = curSameSymp.SymptomID;
                mIDToSymptoms.Add(id, new List<string>());
                foreach (var curSympName in curSameSymp.Symptoms)
                {
                    mIDToSymptoms[id].Add(curSympName);
                    mSymptomToID.Add(curSympName, id);
                }
                mCurrentMaxID = Math.Max(mCurrentMaxID, id);
            }

            mDiseases = new Dictionary<string, ExtendedDiseaseForBuilder>();

            // Get the diseases
            foreach (var curDisease in mToolData.Diseases)
            {
                mDiseases.Add(
                    curDisease.DiseaseName, 
                    new ExtendedDiseaseForBuilder(curDisease, mIDToSymptoms));
            }
        }

        public void SaveToXml(String pFilePath)
        {
            DiagnosisToolXmlMngr.SaveToXML(mToolData, pFilePath);  
        }

        public ExtendedDiseaseForBuilder AddUpdateDisease(Disease pDisease, List<string> pSymptoms)
        {
            var extendedDisease = new ExtendedDiseaseForBuilder();
            extendedDisease.SetDisease(pDisease);
            
            // Keep the ids
            var idsList = new List<Int32>();
           
            // Keep pairs
            var pairs = new List<SympNameIDPair>();
               
            foreach (var curSymp in pSymptoms)
            {
                int id;
                if (mSymptomToID.ContainsKey(curSymp))
                {
                    id = mSymptomToID[curSymp];
                }
                else
                {
                    id = ++mCurrentMaxID;
                    mSymptomToID.Add(curSymp, id);

                    var idsSymps = new List<string>();
                    idsSymps.Add(curSymp);
                    mIDToSymptoms.Add(id, idsSymps);
                }

                if (!idsList.Contains(id))
                {
                    idsList.Add(id);
                }

                pairs.Add(new SympNameIDPair(curSymp, id));
            }
            pDisease.SymptomIDS = idsList.ToArray();
            extendedDisease.GetSymptoms().AddRange(pairs);

            // Update the map
            var diseaseName = extendedDisease.GetDisease().DiseaseName;
            if (mDiseases.ContainsKey(diseaseName))
            {
                mDiseases[diseaseName] = extendedDisease;
            }
            else
            {
                mDiseases.Add(diseaseName, extendedDisease);
            }


            mWorkingDiseaseForBuilder = extendedDisease;

            return mWorkingDiseaseForBuilder;
        }

        public void MergeSymptoms(string pSymp1, string pSymp2)
        {
            var id1 = mSymptomToID[pSymp1];
            var id2 = mSymptomToID[pSymp2];

            mIDToSymptoms[id1].AddRange(mIDToSymptoms[id2]);
            mIDToSymptoms.Remove(id2);

            mSymptomToID[pSymp2] = id1;
        }

        public void SaveDisease()
        {
            if (null == mWorkingDiseaseForBuilder)
            {
                return;
            }

            var sameSympList = new List<SameSymptoms>();
            
            foreach (var key in mIDToSymptoms.Keys)
            {
                var sameSymptoms = new SameSymptoms();
                sameSymptoms.SymptomID = key;
                sameSymptoms.Symptoms = mIDToSymptoms[key].ToArray();

                sameSympList.Add(sameSymptoms);
            }

            mToolData.SameSymptoms = sameSympList.ToArray();

            var foundIndex = LookForDisease(mWorkingDiseaseForBuilder.GetDisease().DiseaseName);
           
            if (-1 != foundIndex)
            {
                mToolData.Diseases[foundIndex] = mWorkingDiseaseForBuilder.GetDisease();
            }
            else
            {
                var asList = new List<Disease>(mToolData.Diseases);
                asList.Add(mWorkingDiseaseForBuilder.GetDisease());

                mToolData.Diseases = asList.ToArray();
            }
        }

        public void DeleteDisease(string diseaseNameToDelete)
        {
            var foundIndex = LookForDisease(diseaseNameToDelete);
            var asList = new List<Disease>(mToolData.Diseases);
            asList.RemoveAt(foundIndex);
            mToolData.Diseases = asList.ToArray();

            // Remove from the array
            mDiseases.Remove(diseaseNameToDelete);
        }

        public int LookForDisease(String pDiseaseName)
        {
            var foundIndex = -1;
            for (int i = 0; i < mToolData.Diseases.Length; i++)
            {
                var disease = mToolData.Diseases[i];
                if (!disease.DiseaseName.Equals(pDiseaseName))
                {
                    continue;
                }
                foundIndex = i;
                break;
            }

            return foundIndex;
        }
    }
}
